package interpreter

import (
	"fmt"
	"parse/src/utils"
	"strconv"
	"time"
)

// 系统函数与系统变量
// 数字初始化
var Print = NewBuiltInFunction("Print")
var PrintRet = NewBuiltInFunction("PrintRet")
var Input = NewBuiltInFunction("Input")
var InputInt = NewBuiltInFunction("InputInt")
var Clear = NewBuiltInFunction("Clear")
var IsNumber = NewBuiltInFunction("IsNumber")
var IsString = NewBuiltInFunction("IsString")
var IsList = NewBuiltInFunction("IsList")
var IsFunction = NewBuiltInFunction("IsFunction")
var Append = NewBuiltInFunction("Append")
var Pop = NewBuiltInFunction("Pop")
var Extend = NewBuiltInFunction("Extend")
var Len = NewBuiltInFunction("Len")
var Run = NewBuiltInFunction("Run")
var TimeStamp = NewBuiltInFunction("TimeStamp") // 当前的时间戳

// 函数
type BuiltInFunction struct {
	*BaseFunction
}

// 实例化
func NewBuiltInFunction(name string) *BuiltInFunction {
	temp := &BuiltInFunction{NewBaseFunction(name)}
	temp.InitBuiltInFunction(name)
	return temp
}

// 初始化
func (b *BuiltInFunction) InitBuiltInFunction(name string) {
	b.InitBaseFunction(name)
}

func (b *BuiltInFunction) Execute(args []interface{}) *RTResult {
	res := NewRTResult()
	execCtx := b.GenerateNewContext("")

	methodName := "Execute" + b.Name
	//method := utils.GetItemAttribute(b,methodName)
	// todo 获取函数的参数名字
	//method := reflect.ValueOf(b).FieldByName(methodName)
	var paramsArr []string
	for key, _ := range args {
		paramsArr = append(paramsArr, "system.BuiltInFunction."+methodName+strconv.Itoa(key))
	}

	res.Register(b.CheckAndPopulateArgs(paramsArr, args, execCtx))
	if res.ShouldReturn() != nil {
		return res
	}
	funRes := utils.RunFuncOther(b, methodName, execCtx)
	returnValue := res.Register(funRes.(*RTResult))
	if res.ShouldReturn() != nil {
		return res
	}
	return res.Success(returnValue)
}

// 拷贝
func (b *BuiltInFunction) Copy() *BuiltInFunction {
	copy_ := NewBuiltInFunction(b.Name)
	copy_.SetContext(b.Context)
	copy_.SetPos(b.PosStart, b.PosEnd)
	return copy_
}

// 执行打印
func (b *BuiltInFunction) ExecuteCopy() *BuiltInFunction {
	copy_ := NewBuiltInFunction(b.Name)
	copy_.SetContext(b.Context)
	copy_.SetPos(b.PosStart, b.PosEnd)
	return copy_
}

// 系统函数-打印
func (b *BuiltInFunction) ExecutePrint(execCtx *Context) interface{} {
	t := execCtx.SymbolTable.Get("system.BuiltInFunction.ExecutePrint0")
	switch t.(type) {
	case *String:
		fmt.Println(t.(*String).Value)
	case *Number:
		fmt.Println(t.(*Number).Value)
	}
	r := NewRTResult()
	return r.Success(nil)
}

// 系统函数-打印-有返回值
func (b *BuiltInFunction) ExecutePrintRet(execCtx *Context) interface{} {
	t := execCtx.SymbolTable.Get("system.BuiltInFunction.ExecutePrintRet0")
	switch t.(type) {
	case *String:
		fmt.Println(t.(*String).Value)
	case *Number:
		fmt.Println(t.(*Number).Value)
	}
	r := NewRTResult()
	return r.Success(t)
}

// 系统函数-clear
func (b *BuiltInFunction) ExecuteClear(execCtx *Context) interface{} {
	t := execCtx.SymbolTable.Get("system.BuiltInFunction.ExecuteClear0")
	switch t.(type) {
	case *String:
		fmt.Println(t.(*String).Value)
	}
	r := NewRTResult()
	return r.Success(Null)
}

// 系统函数-clear
func (b *BuiltInFunction) ExecuteTimeStamp(execCtx *Context) interface{} {
	r := NewRTResult()
	return r.Success(NewNumber(float64(time.Now().UnixNano())))
}
